package models

import (
	"slices"
	"time"

	"cashew.com/cashew_common/constants"
	"github.com/beego/beego/v2/client/orm"
)

type Black_list struct {
	Id         int64
	OperatorId int64
	TargetId   int64
	CreateTime int64
	UpdateTime int64
	Status     int
}

func init() {
	orm.RegisterModel(new(Black_list))
}

func SetBlack_Status(userId, targetId int64, status int) error {
	o := orm.NewOrm()
	if status == constants.BLACKLIST_STATUS_UNBLOCKED {
		updateData := orm.Params{"status": constants.BLACKLIST_STATUS_UNBLOCKED, "update_time": time.Now().Unix()}
		_, err := o.QueryTable(new(Black_list)).Filter("target_id", targetId).Filter("operator_id", userId).Filter("status", constants.BLACKLIST_STATUS_BLOCKED).Update(updateData)
		if err != nil {
			return err
		}

		return nil
	} else {
		v := &Black_list{}
		err := o.QueryTable(new(Black_list)).Filter("target_id", targetId).Filter("operator_id", userId).Filter("status", constants.BLACKLIST_STATUS_BLOCKED).One(v)
		if err == nil {
			return nil
		}

		insertData := &Black_list{
			OperatorId: userId,
			TargetId:   targetId,
			CreateTime: time.Now().Unix(),
			Status:     constants.BLACKLIST_STATUS_BLOCKED,
		}

		_, err = o.Insert(insertData)
		if err != nil {
			return err
		}

		return nil
	}
}

func GetBlackCountByOperatorId(operatorId int64) (int64, error) {
	count, err := orm.NewOrm().QueryTable(new(Black_list)).Filter("operator_id", operatorId).Filter("status", constants.BLACKLIST_STATUS_BLOCKED).Count()

	if err != nil {
		return 0, err
	}
	return count, nil
}

func GetAllBlack_listByOperatorId(operatorId int64, page int, perPage int) ([]Black_list, error) {
	result := []Black_list{}
	fields := []string{"operator_id", "target_id", "create_time"}
	order := []string{"-create_time", "-target_id"}
	offset := (page - 1) * perPage

	_, err := orm.NewOrm().QueryTable(new(Black_list)).Filter("operator_id", operatorId).Filter("status", constants.BLACKLIST_STATUS_BLOCKED).Offset(offset).Limit(perPage).OrderBy(order...).RelatedSel().All(&result, fields...)

	if err != nil {
		return nil, err
	}
	return result, nil
}

func GetBlack_listCountByOperatorId(operatorId int64) (int64, error) {
	count, err := orm.NewOrm().QueryTable(new(Black_list)).Filter("operator_id", operatorId).Filter("status", constants.BLACKLIST_STATUS_BLOCKED).RelatedSel().Count()

	if err != nil {
		return 0, err
	}
	return count, nil
}

// 判断是否是黑名单关系
func IsBlack(viewerId, anchorId int64) (exist bool) {
	o := orm.NewOrm()
	exist = o.QueryTable(new(Black_list)).Filter("target_id", viewerId).Filter("operator_id", anchorId).Filter("status", 1).RelatedSel().Exist()

	if exist {
		return
	}
	exist = o.QueryTable(new(Black_list)).Filter("operator_id", viewerId).Filter("target_id", anchorId).Filter("status", 1).RelatedSel().Exist()

	return
}

// 判断拉黑状态
func BlackStatus(userId, toUserId int64) (blackStatus int) {
	o := orm.NewOrm()
	blackStatus = constants.BLACK_STATUS_NONE
	exist := o.QueryTable(new(Black_list)).Filter("target_id", userId).Filter("operator_id", toUserId).Filter("status", 1).RelatedSel().Exist()

	if exist {
		blackStatus = constants.BLACK_STATUS_FROM_OTHER
		return
	}
	exist = o.QueryTable(new(Black_list)).Filter("operator_id", userId).Filter("target_id", toUserId).Filter("status", 1).RelatedSel().Exist()
	if exist {
		blackStatus = constants.BLACK_STATUS_FROM_ME
		return
	}

	return
}

func IsBlackDist(operatorId int64, targetId int64) (exist bool) {
	o := orm.NewOrm()
	//v := &Black_list{}
	exist = o.QueryTable(new(Black_list)).Filter("operator_id", operatorId).Filter("target_id", targetId).Filter("status", constants.BLACKLIST_STATUS_BLOCKED).RelatedSel().Exist()
	return
}

func GetBlackAnchorIdsByUserId(userId int64) ([]int64, error) {
	var ids []int64
	result := []Black_list{}
	_, err := orm.NewOrm().QueryTable(new(Black_list)).Filter("operator_id", userId).
		Filter("status", constants.BLACKLIST_STATUS_BLOCKED).RelatedSel().All(&result, "target_id")
	if err != nil {
		return nil, err
	}
	for _, v := range result {
		ids = append(ids, v.TargetId)
	}

	result = []Black_list{}
	_, err = orm.NewOrm().QueryTable(new(Black_list)).Filter("target_id", userId).
		Filter("status", constants.BLACKLIST_STATUS_BLOCKED).RelatedSel().All(&result, "operator_id")
	if err != nil {
		return nil, err
	}
	for _, v2 := range result {
		if slices.Contains(ids, v2.OperatorId) == false {
			ids = append(ids, v2.TargetId)
		}
	}

	return ids, nil
}
